package com.zmn.oms.admin.controller.conf.channel;

import com.alibaba.fastjson.JSON;
import com.google.api.client.util.Lists;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.dro.ChannelSettleDRO;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.channel.dubbo.interfaces.channel.settle.ChannelSettleListRemoteService;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.dto2.data.LayuiTableDO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.mcc.common.dto.dept.DeptDRO;
import com.zmn.mcc.dubbo.interfaces.dept.DeptListRemoteService;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.conf.channel.ConfOrderChannelBService;
import com.zmn.oms.common.dro.conf.channel.ConfOrderChannelDRO;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.enums.ConfChannelReceivablesLimitEnum;
import com.zmn.oms.common.enums.ConfChannelWorkOrderTypeEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.conf.treenode.TreeNodeDTO;
import com.zmn.oms.model.entity.conf.channel.ConfOrderChannel;
import com.zmn.oms.model.entity.conf.channel.ConfOrderChannelQuery;
import com.zmn.oms.model.vo.conf.channel.ConfOrderChannelVO;
import com.zmn.oms.services.interfaces.conf.channel.ConfOrderChannelService;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 渠道ListController
 *
 * @author xiangjunming
 * @since 2019 /08/19 19:10:20
 */
@Controller
@RequestMapping("/conf/channel")
public class ConfOrderChannelController extends OmsBaseController {

	private Logger logger = LoggerFactory.getLogger(ConfOrderChannelController.class);

	@Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false, timeout = 10000)
	private ChannelListRemoteService channelListRemoteService;
	@Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false, timeout = 10000)
	private ChannelSettleListRemoteService channelSettleListRemoteService;
	@Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false, timeout = 10000)
	private DeptListRemoteService deptListRemoteService;
	@Resource
	private ConfOrderChannelService confOrderChannelService;
	@Resource
	private ConfOrderChannelBService confOrderChannelBService;

	/**
	 * 跳转到列表页面中
	 *
	 * @param mv
	 * @return
	 * @author liudi
	 */
	@RequestMapping(value = "/list")
	public ModelAndView toList(ModelAndView mv) {
		mv.setViewName("conf/channel/list");
		return mv;
	}

	/**
	 * 查询列表 ajax
	 *
	 * @param query
	 * @return
	 * @author liudi
	 * @since: 2022/2/18 11:24
	 */
	@RequestMapping(value = "/ajax/list")
	@ResponseBody
	public ResultDTO ajaxList(ConfOrderChannelQuery query) {
		List<ConfOrderChannelVO> channelVOList = confOrderChannelBService.listPageByQuery(query);
		LayuiTableDO<ConfOrderChannelVO> data = new LayuiTableDO();
		data.setCount(query.getTotalCount());
		data.setData(channelVOList);
		return ResultDTO.success(data);
	}


	/**
	 * 删除
	 *
	 * @param channelIds
	 * @return
	 * @author liudi
	 * @since: 2022/2/20 17:39
	 */
	@RequestMapping(value = "/delete")
	@ResponseBody
	public ResultDTO delete(String channelIds) {
		try {
			List<Integer> ids;
			if (StringUtils.isNotBlank(channelIds)) {
				ids = Arrays.asList(channelIds.split(","))
						.stream()
						.map(Integer::parseInt)
						.collect(Collectors.toList());
			} else {
				ids = Lists.newArrayList();
			}
			confOrderChannelService.deleteByChannelIds(ids);
			return ResultDTO.success();
		} catch (Exception e) {
			e.printStackTrace();
			return ResultDTO.fail(e.getMessage());
		}
	}

	/**
	 * 渠道订单配置
	 *
	 * @param channelId the channel id
	 * @return the model and view
	 * @author xiangjunming
	 * @since 2019/9/5
	 */
	@RequestMapping(value = "/addEdit")
	public ModelAndView addEdit(Integer channelId) throws OmsBaseException {
		ModelAndView mav = new ModelAndView("conf/channel/detail");
		ChannelDRO channelDRO;
		ConfOrderChannel orderConfig;
		List<VtDTO> channelList;
		List<Integer> expandedKeys;

		if (Objects.nonNull(channelId)) {

			// 获取渠道信息
			ResponseDTO<ChannelDRO> channelDROResponseDTO = channelListRemoteService.getByChannelId(channelId);
			if (!channelDROResponseDTO.isSuccess()) {
				throw new OmsBaseException(channelDROResponseDTO.getMessage());
			}
			channelDRO = channelDROResponseDTO.getData();

			// 获取渠道订单配置信息
			orderConfig = Optional.ofNullable(confOrderChannelService.findByKey(channelId)).orElse(new ConfOrderChannel());

			// 获取二级渠道
			ResponseDTO<List<ChannelDRO>> listResponseDTO = channelListRemoteService.listTwoLevelChannel(null, null);
			if (CollectionUtils.isEmpty(listResponseDTO.getData())) {
				logger.info("获取二级渠道数据失败，响应结果：{}", listResponseDTO);
				throw new OmsBaseException(listResponseDTO.getMessage());
			}

			logger.info("获取二级渠道数据：{}", listResponseDTO);
			channelList = listResponseDTO.getData().stream()
					.map(m -> new VtDTO(m.getChannelId(), m.getName()))
					.collect(Collectors.toList());

			// 根节点id
			List<DeptDRO> parentNodes = new ArrayList<>();
			expandedKeys = new ArrayList<>();
			if (Objects.nonNull(orderConfig.getPriceAuditDeptId())) {
				Integer parent = getParentId(orderConfig.getPriceAuditDeptId(), parentNodes);
				expandedKeys.addAll(parentNodes.stream().map(DeptDRO::getDeptId).collect(Collectors.toList()));
				expandedKeys.add(parent);
			}
		} else {
			channelDRO = new ChannelDRO();
			orderConfig = new ConfOrderChannel();
			orderConfig.setWorkOrderCancelType(String.valueOf(ConfChannelWorkOrderTypeEnum.CONSTS_AUTOCANCEL));
			channelList = Lists.newArrayList();
			expandedKeys = Lists.newArrayList();
		}

		// 组装页面参数
		mav.addObject("obj", channelDRO);
		mav.addObject("channelList", channelList);
		mav.addObject("orderConfig", orderConfig);
		mav.addObject("expandedKeys", expandedKeys);
		mav.addObject("receivablesLimits", ConfChannelReceivablesLimitEnum.values());
		mav.addObject("completeOrCancelTypes", ConfChannelWorkOrderTypeEnum.completeOrCancelType());
		return mav;
	}


	/**
	 * 修改渠道订单配置
	 *
	 * @param confOrderChannel the channel new
	 * @return the result dto
	 * @author xiangjunming
	 * @modify linfeng 渠道订单配置表从渠道表独立出来
	 * @since 2019/9/5
	 */
	@RequestMapping("modifyOrderConfig")
	@ResponseBody
	public ResponseDTO modifyOrderConfig(@RequestBody ConfOrderChannel confOrderChannel) {
		String lable = "修改渠道订单配置";
		try {
			logger.info("更改渠道订单配置 入参 ：{}", JSON.toJSONString(confOrderChannel));
			confOrderChannelBService.modifyOrderConfig(confOrderChannel);
			return ResponseDTO.success(confOrderChannel.getChannelId(), String.format("%s成功！", lable));
		} catch (Exception e) {
			logger.error("error:", e);
			return ResponseDTO.fail(String.format("%s失败！", lable));
		}
	}

	/**
	 * <b>从 plat 项目迁移过来的方法<b/>
	 *
	 * @param deptId
	 * @param parentNodes
	 * @return
	 */
	private Integer getParentId(Integer deptId, List<DeptDRO> parentNodes) {
		ResponseDTO<DeptDRO> resSelectDRO = deptListRemoteService.getDept(deptId);
		if (resSelectDRO.isSuccess()) {
			// 当前节点的父节点
			DeptDRO selectDRO = resSelectDRO.getData();
			Integer selectParentId = selectDRO.getParentId();
			if (!Objects.equals(selectParentId, GlobalConsts.NO)) {
				parentNodes.add(selectDRO);
				return getParentId(selectParentId, parentNodes);
			} else {
				return selectDRO.getDeptId();
			}
		}
		return null;
	}

	/**
	 * 部门联动
	 *
	 * @param parentId
	 */
	@RequestMapping(value = "listChilds")
	@ResponseBody
	public ResponseDTO listChilds(@RequestParam(value = "parentId", defaultValue = "1") Integer parentId,
	                              @RequestParam(value = "selectVal", defaultValue = "0") Integer selectVal) {

		ResponseDTO<List<DeptDRO>> listResponseDTO = deptListRemoteService.listDeptByParentId(parentId, null);
		if (!listResponseDTO.isSuccess()) {
			return ResponseDTO.fail(listResponseDTO.getMessage());
		}

		List<TreeNodeDTO> deptDROList = listResponseDTO.getData().stream()
				.map(deptDRO -> new TreeNodeDTO(deptDRO.getDeptName(), deptDRO.getDeptId(), Objects.equals(selectVal, deptDRO.getDeptId())))
				.collect(Collectors.toList());

		// 初次加载如果存在选中的值，加载它对应的父节点
		if (!NumberUtil.isNullOrZero(selectVal)) {
			List<DeptDRO> parentNodes = new ArrayList<>();

			// 根节点id
			Integer levelOneParentId = getParentId(selectVal, parentNodes);

			if (!Objects.equals(selectVal, levelOneParentId)) {

				// 当前节点的顶级节点。
				TreeNodeDTO topNode = deptDROList.stream()
						.filter(e -> Objects.equals(e.getValue(), levelOneParentId))
						.findFirst()
						.get();

				// 从后往前遍历
				for (int j = parentNodes.size() - 1; j >= 0; j--) {
					DeptDRO oneDro = parentNodes.get(j);
					ResponseDTO<List<DeptDRO>> oneDroDTO = deptListRemoteService.listDeptByParentId(oneDro.getParentId(), null);
					List<TreeNodeDTO> vtOneItems = oneDroDTO.getData().stream()
							.map(deptDRO -> new TreeNodeDTO(deptDRO.getDeptName(), deptDRO.getDeptId(), Objects.equals(selectVal, deptDRO.getDeptId())))
							.collect(Collectors.toList());

					if (CollectionUtils.isEmpty(topNode.getChildren())) {
						topNode.setChildren(vtOneItems);
					} else {
						topNode.getChildren().stream()
								.filter(e -> Objects.equals(e.getValue(), oneDro.getParentId()))
								.findFirst()
								.get()
								.setChildren(vtOneItems);
					}
				}
			}
		}

		return ResponseDTO.success(deptDROList, String.format("共%s个部门", deptDROList.size()));
	}

	/**
	 * 获取渠道信息
	 * @param channelId
	 * @return
	 */
	@GetMapping("/getChannelInfo")
	@ResponseBody
	public ResultDTO getChannelInfo(Integer channelId) {
		ConfOrderChannelDRO confOrderChannelDRO = null;
		try {
			confOrderChannelDRO = confOrderChannelBService.getByChannelId(channelId);
		} catch (OmsBaseException omsBaseException) {
			omsBaseException.printStackTrace();
		}
		if (Objects.isNull(confOrderChannelDRO)) {
			return ResultDTO.fail("无法获取渠道信息");
		}
		ConfOrderChannelVO vo = new ConfOrderChannelVO();
		vo.setSelectMarketingShop(confOrderChannelDRO.getSelectMarketingShop());
		return ResultDTO.success(vo);
	}

	/**
	 * 获取结算信息
	 *
	 * @param channelId 渠道id
	 * @return 合并结算：1.否 2.是
	 * @author xujie
	 * @since 2021/04/14
	 */
	protected Integer getMergeSettle(Integer channelId) {
		if (channelId == null) {
			return GlobalConsts.NO;
		}

		ResponseDTO<ChannelSettleDRO> channelSettleDRO = channelSettleListRemoteService.getByChannelId(channelId);
		if (!channelSettleDRO.isSuccess() || Objects.isNull(channelSettleDRO.getData())) {
			return GlobalConsts.NO;
		} else {
			return channelSettleDRO.getData().getMergeSettle();
		}
	}
}